﻿'use strict';

(function ($, window, document) {
    if (!$) {
        return console.error('in datetimepicker.kmhealth.js, $ is null');
    }

    $.fn.extend({
        datetimepicker: function datetimepicker() {
            var _this = this;

            var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

            $(function () {
                var _options$className = options.className;
                var className = _options$className === undefined ? '' : _options$className;
                var initDate = options.initDate;
                var startDate = options.startDate;
                var endDate = options.endDate;
                var _options$dateClickCondition = options.dateClickCondition;
                var dateClickCondition = _options$dateClickCondition === undefined ? function () {
                    return true;
                } : _options$dateClickCondition;
                var _options$monthClickCondition = options.monthClickCondition;
                var monthClickCondition = _options$monthClickCondition === undefined ? function () {
                    return true;
                } : _options$monthClickCondition;
                var _options$yearClickCondition = options.yearClickCondition;
                var yearClickCondition = _options$yearClickCondition === undefined ? function () {
                    return true;
                } : _options$yearClickCondition;
                var _options$format = options.format;
                var format = _options$format === undefined ? 'yyyy/MM/dd' : _options$format;

                var displayDate = initDate;
                var selectDate = initDate;
                var template = table.template({
                    className: className
                });

                var button = $(_this);
                var picker = $(template.main).appendTo("body");

                function formatDate(date) {

                    var unitList = format.split(/[ymMd]*/);

                    //去除正则所匹配的起始结尾空格
                    unitList.splice(0, 1);

                    var ym = unitList[0];
                    var md = unitList[1];
                    var year = date.getFullYear() + '';
                    var month = date.getMonth() + 1;
                    var day = date.getDate();

                    month = (month < 10 ? '0' : '') + month;
                    day = (day < 10 ? '0' : '') + day;

                    var y = /[y]+/g.exec(format)[0] || 'yyyy';
                    var M = /[M]+/g.exec(format)[0] || 'MM';
                    var d = /[d]+/g.exec(format)[0] || 'dd';

                    year = year.substr(4 - y.length, 4);
                    month = month.substr(2 - M.length, 4);
                    day = day.substr(2 - d.length, 4);

                    return '' + year + ym + month + md + day;
                }

                if (initDate instanceof Date) {
                    button.val(formatDate(initDate));
                }

                button.on('click', function (e) {
                    //e.preventDefault();
                    //e.stopPropagation();

                    displayDate = selectDate || new Date();

                    //展开与隐藏时间控件
                    var offset = button.offset();
                    var showDate = displayDate;

                    picker.css({
                        left: offset.left,
                        top: offset.top + button.outerHeight()
                    }).toggleClass('on');

                    picker.width(button.outerWidth());

                    if (picker.hasClass('on')) {
                        $('.select-date,.select-month,.select-year').hide().filter('.select-date').show();

                        createDatePage(showDate);

                        if (selectDate instanceof Date) {
                            picker.find('.select-date .datetime-tr td').each(function (index, elm) {
                                var $elm = $(elm);

                                var _$elm$data = $elm.data('date');

                                var year = _$elm$data.year;
                                var month = _$elm$data.month;
                                var date = _$elm$data.date;

                                if (year === selectDate.getFullYear() && month === selectDate.getMonth() && date === selectDate.getDate()) {
                                    $elm.addClass('on');
                                }
                            });
                        }
                    }
                });

                $(document.body).on('click', function (e) {
                    var target = $(e.target);
                    if (picker.is(target) || picker.find(target).length > 0 || button.is(target) || button.find(target).length > 0) {
                        return;
                    }

                    picker.removeClass('on');
                });

                //控件事件
                picker.find('.dtp-left').on('click', function (e) {
                    var target = $(e.currentTarget);
                    var selectDiv = target.parents('.select-date,.select-month,.select-year');

                    if (selectDiv.hasClass('select-date')) {
                        var showDate = new Date(displayDate.getFullYear(), displayDate.getMonth() - 1, 1);

                        if (startDate instanceof Date) {
                            var displayCurrentDate = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1);
                            var start = new Date(startDate);
                            start.setDate(2);

                            if (displayCurrentDate < start) {
                                return;
                            }
                        }

                        displayDate = showDate;

                        createDatePage(showDate);
                        button.trigger('date.left.click');

                        button.trigger('date.general', [picker.find('.select-date table')]);
                    } else if (selectDiv.hasClass('select-month')) {
                        var year = displayDate.getFullYear() - 1;

                        if (startDate instanceof Date) {

                            if (year < startDate.getFullYear()) {
                                return;
                            }
                        }

                        displayDate.setFullYear(year);
                        createMonthPage(displayDate);
                        selectDiv.find('.year').text(year);
                    } else if (selectDiv.hasClass('select-year')) {
                        var year = displayDate.getFullYear() - 10;

                        if (startDate instanceof Date) {
                            var displayCurrentDate = new Date(year, displayDate.getMonth(), 1);
                            var start = new Date(startDate);
                            start.setDate(2);

                            if (displayCurrentDate < start) {
                                return;
                            }
                        }

                        displayDate.setFullYear(year);
                        createAllYearPage(displayDate);
                    }
                });

                picker.find('table').on('click', '.datetime-tr a', function (e) {
                    var target = $(e.currentTarget);
                    var selectDiv = target.parents('.select-date,.select-month,.select-year');
                    var td = target.parents('td');

                    if (td.hasClass('not-active')) {
                        return;
                    }

                    if (selectDiv.hasClass('select-date')) {
                        var _td$data = td.data('date');

                        var date = _td$data.date;
                        var month = _td$data.month;
                        var year = _td$data.year;

                        var dataDate = new Date(year, month, date);

                        if (!dateClickCondition(target.parents('td'))) {
                            return;
                        }

                        button.val(formatDate(dataDate));
                        picker.removeClass('on');

                        displayDate = new Date(dataDate);
                        selectDate = new Date(dataDate);

                        button.trigger('date.change', [target]);
                    } else if (selectDiv.hasClass('select-month')) {

                        if (!monthClickCondition(target.parents('td'))) {
                            return;
                        }

                        displayDate.setMonth(td.data('month'));
                        selectDiv.hide().next().show();

                        createDatePage(displayDate);
                        selectDate = new Date(displayDate);
                        button.trigger('month.change', [target]);
                    } else if (selectDiv.hasClass('select-year')) {

                        if (!yearClickCondition(target.parents('td'))) {
                            return;
                        }

                        displayDate.setYear(td.data('year'));

                        selectDiv.hide().next().show();

                        createMonthPage(displayDate);
                        selectDate = new Date(displayDate);
                        button.trigger('year.change', [target]);
                    }
                });

                picker.find('.dtp-right').on('click', function (e) {
                    var target = $(e.currentTarget);
                    var selectDiv = target.parents('.select-date,.select-month,.select-year');

                    if (selectDiv.hasClass('select-date')) {
                        var showDate = new Date(displayDate.getFullYear(), displayDate.getMonth() + 1, 1);

                        if (endDate instanceof Date) {
                            var displayCurrentDate = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1);
                            var end = new Date(endDate);

                            end.setMonth(end.getMonth() - 1);
                            end.setDate(1);

                            if (displayCurrentDate > end) {
                                return;
                            }
                        }

                        displayDate = showDate;

                        createDatePage(showDate);
                        button.trigger('date.right.click');

                        button.trigger('date.general', [picker.find('.select-date table')]);
                    } else if (selectDiv.hasClass('select-month')) {
                        var year = displayDate.getFullYear() + 1;

                        if (endDate instanceof Date) {
                            var endYear = endDate.getFullYear();
                            if (year > endYear) {
                                return;
                            }
                        }

                        displayDate.setFullYear(year);
                        selectDiv.find('.year').text(year);
                        createMonthPage(displayDate);
                    } else if (selectDiv.hasClass('select-year')) {
                        var year = displayDate.getFullYear() + 10;

                        if (endDate instanceof Date) {
                            var displayCurrentDate = new Date(year, displayDate.getMonth(), 1);
                            var end = new Date(endDate);

                            end.setMonth(end.getMonth() - 1);
                            end.setDate(1);

                            if (displayCurrentDate > end) {
                                return;
                            }
                        }

                        displayDate.setFullYear(year);
                        createAllYearPage(displayDate);
                        button.trigger('year.change', [target]);
                    }
                });

                picker.find('.year').on('click', function (e) {
                    var target = $(e.currentTarget);
                    var selectDiv = target.parents('.select-date,.select-month,.select-year');

                    $('.select-date,.select-month,.select-year').hide();

                    if (selectDiv.hasClass('select-date')) {
                        (function () {
                            var selectMonth = $('.select-month').show();
                            var month = displayDate.getMonth();

                            createMonthPage(displayDate);

                            selectMonth.find('table .datetime-tr td').each(function (index, elem) {
                                var $elem = $(elem);

                                if ($elem.data('month') === month) {
                                    $elem.addClass('on');
                                }
                            });
                        })();
                    } else if (selectDiv.hasClass('select-month')) {
                        (function () {
                            var selectYear = $('.select-year').show();
                            var year = displayDate.getFullYear();

                            createAllYearPage(displayDate);

                            selectYear.find('table .datetime-tr td').each(function (index, elem) {
                                var $elem = $(elem);
                                var elmYear = $elem.data('year');

                                if (elmYear === year) {
                                    $elem.addClass('on');
                                }
                            });
                        })();
                    } else if (selectDiv.hasClass('select-year')) {
                        $('.select-year').show();
                        return;
                    }
                });

                $(window).on('resize', function () {
                    var offset = button.offset();
                    picker.width(button.outerWidth());

                    picker.css({
                        left: offset.left,
                        top: offset.top + button.outerHeight()
                    });
                });

                function createDatePage(showDate) {
                    picker.find('.select-date .datetime-tr').remove();

                    var currentDateGroup = new Date(showDate.getFullYear(), showDate.getMonth() + 1, 0);
                    var index = new Date(currentDateGroup.getFullYear(), currentDateGroup.getMonth(), 1).getDay();
                    var prevDatetime = new Date(showDate.getFullYear(), showDate.getMonth(), 0);
                    var nextDatetime = new Date(showDate.getFullYear(), showDate.getMonth() + 2, 0);
                    var prevDate = prevDatetime.getDate();
                    var dateArray = [];

                    if (index > 0) {
                        for (var i = 1; i <= index; i++) {
                            var num = index - i;

                            dateArray.push({
                                isCurrent: false,
                                date: prevDate - num,
                                month: prevDatetime.getMonth(),
                                year: prevDatetime.getFullYear()
                            });
                        }
                    }

                    for (var i = 1; i <= currentDateGroup.getDate(); i++) {
                        dateArray.push({
                            isCurrent: true,
                            date: i,
                            month: currentDateGroup.getMonth(),
                            year: currentDateGroup.getFullYear()
                        });
                    }

                    var length = 35 - dateArray.length;
                    length = length <= 0 ? 42 - dateArray.length : length;

                    for (var i = 1; i <= length; i++) {
                        dateArray.push({
                            isCurrent: false,
                            date: i,
                            month: nextDatetime.getMonth(),
                            year: nextDatetime.getFullYear()
                        });
                    }

                    var temp = [].concat(dateArray);
                    dateArray.splice(0, dateArray.length);

                    while (temp.length > 0) {
                        dateArray.push(temp.splice(0, 7));
                    }

                    var selectDateList = dateArray.map(function (x) {
                        var tr = $(template.tr());
                        tr.append(x.map(function (n) {
                            var elmDate = new Date(n.year, n.month, n.date);
                            var $elm = $(template.td(n.date)).addClass(n.isCurrent ? '' : 'graw').data('date', n);

                            if (startDate instanceof Date) {
                                if (elmDate < startDate) {
                                    $elm.addClass('not-active');
                                }
                            }

                            if (endDate instanceof Date) {
                                if (elmDate > endDate) {
                                    $elm.addClass('not-active');
                                }
                            }

                            return $elm;
                        }));

                        return tr;
                    });

                    var month = currentDateGroup.getMonth() + 1;

                    picker.find('.select-date table').append(selectDateList);
                    picker.find('.select-date .year').text(currentDateGroup.getFullYear() + '-' + ((month >= 10 ? '' : '0') + month));

                    button.trigger('date.general', [picker.find('.select-date table')]);
                }

                function createMonthPage(showDate) {
                    var year = showDate.getFullYear();

                    picker.find('.select-month .datetime-tr').remove();

                    var monthList = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];

                    var group = monthList.map(function (x) {
                        return $(template.tr()).append(x.map(function (n) {
                            var td = $(template.td((n < 10 ? '0' : '') + n));
                            var month = n - 1;
                            if (startDate instanceof Date && year <= startDate.getFullYear()) {

                                if (month < startDate.getMonth()) {
                                    td.addClass('not-active');
                                }
                            }

                            if (endDate instanceof Date && year >= endDate.getFullYear()) {

                                if (month > endDate.getMonth()) {
                                    td.addClass('not-active');
                                }
                            }

                            td.data('month', month);

                            return td;
                        }));
                    });

                    picker.find('.select-month table').append(group).removeData('year');
                    picker.find('.select-month .year').text(showDate.getFullYear());

                    button.trigger('month.general', [picker.find('.select-month table')]);
                }

                function createAllYearPage(showDate) {
                    picker.find('.select-year .datetime-tr').remove();

                    var year = showDate.getFullYear();
                    var sub = parseInt(year / 10) * 10;
                    var list = [sub - 1];
                    for (var i = 0; i < 11; i++) {
                        list.push(sub + i);
                    }

                    var temp = [].concat(list);
                    list = [];
                    while (temp.length > 0) {
                        list.push(temp.splice(0, 4));
                    }

                    var trGroup = list.map(function (x) {
                        return $(template.tr()).append(x.map(function (n) {
                            var td = $(template.td(n)).data('year', n);

                            if (startDate instanceof Date && endDate instanceof Date) {
                                var startYear = startDate.getFullYear();
                                var endYear = endDate.getFullYear();

                                if (n < startYear || n > endYear) {
                                    td.addClass('not-active');
                                }
                            }

                            return td;
                        }));
                    });

                    picker.find('.select-year table').append(trGroup);
                    picker.find('.select-year .year').text(sub - 1 + '-' + (sub + 10));

                    button.trigger('year.general', [picker.find('.select-year table')]);
                }
            });

            return $(this);
        }
    });

    var table = (function () {
        return {
            skin: function skin() {
                return '\n                <style>\n                    .datetime-picker-default-skin{position:absolute;overflow:visible;width:340px;-webkit-border-radius:3px;border-radius:3px;border-top:1px solid #ddd;z-index:2;top:0;left:0;visibility:hidden;}.datetime-picker-default-skin.on{visibility:visible;}.datetime-picker-default-skin.on .datetime-picker-group{opacity:1;visibility:visible;-moz-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);-webkit-transform:translate(0,0);transform:translate(0,0);}.datetime-picker-group{position:relative;visibility:hidden;opacity:0;padding:5px 2px;background:#fff;-moz-transition:.2s linear;-o-transition:.2s linear;-webkit-transition:.2s linear;transition:.2s linear;-moz-transform:translate(0,-5px);-ms-transform:translate(0,-5px);-o-transform:translate(0,-5px);-webkit-transform:translate(0,-5px);transform:translate(0,-5px);}.datetime-picker-group .header{text-align:center;overflow:hidden;}.datetime-picker-group .header .dtp-left,.datetime-picker-group .header .dtp-right{width:30px;height:30px;line-height:30px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;font-weight:bold;color:#444;text-align:center;display:block;margin:0 auto;}.datetime-picker-group .header .dtp-left:hover,.datetime-picker-group .header .dtp-right:hover{background:#eee;}.datetime-picker-group .header .year{height:30px;line-height:30px;overflow:hidden;font-size:1.4rem;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;font-weight:bold;color:#444;}.datetime-picker-group .header .year:hover{background:#eee;}.datetime-picker-group table{width:100%;border:none;padding:0;margin:0;}.datetime-picker-group table td,.datetime-picker-group table th{text-align:center;height:40px;line-height:40px;font-size:1.1rem;padding:3px 0;}.datetime-picker-group table td a{color:#444;display:block;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%;width:40px;max-width:14.28571429%;margin:0 auto;border:1px solid transparent;}.datetime-picker-group table td a:hover{background:#eee;}.datetime-picker-group table td.on a{background:#0090ff;color:#fff;}.datetime-picker-group table td.not-active a{background:transparent !important;color:#ddd !important;cursor:default;}.datetime-picker-group table td.graw a{color:#999;}.datetime-picker-group .select-month td,.datetime-picker-group .select-year td{height:70px;line-height:70px;}.datetime-picker-group .select-month td a,.datetime-picker-group .select-year td a{width:70px;}.datetime-picker-group .select-year tr:nth-child(2) td:first-child a{color:#999;}.datetime-picker-group .select-year tr:last-child td:last-child a{color:#999;}\n                </style>\n            '.trim();
            },

            template: function template() {
                var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

                return {
                    tr: function tr() {
                        return $.trim('<tr class="datetime-tr"></tr>');
                    },
                    td: function td(x) {
                        return '<td><a href="javascript:void(0);">' + x + '</a></td>';
                    },
                    //td: (sources = [], callback) => {
                    //    return $.trim(`
                    //    <tr class="datetime-tr">
                    //        ${sources.map((x, index) => $.trim(`
                    //            <td><a href="javascript:void(0);">${x}</a></td>
                    //        `)).join('')}
                    //    </tr>`);
                    //},

                    main: $.trim('\n                        <div class="' + (options.className || 'datetime-picker-default-skin') + '">\n                          <div class="datetime-picker-group">\n                            <div class="select-year" style="display:none;">\n                                <table>\n                                    <tr class="header">\n                                        <th><a href="javascript:void(0);" class="booticon dtp-left booticon-left"></a></th>\n                                        <th colspan="2"><a href="javascript:void(0);"><div class="year"></div></a></th>\n                                        <th><a href="javascript:void(0);" class="booticon dtp-right booticon-right"></a></th>\n                                    </tr>\n                                </table>\n                            </div>\n                            <div class="select-month" style="display: none;">\n                                <table>\n                                    <tr class="header">\n                                        <th><a href="javascript:void(0);" class="booticon dtp-left booticon-left"></a></th>\n                                        <th colspan="2"><a href="javascript:void(0);"><div class="year"></div></a></th>\n                                        <th><a href="javascript:void(0);" class="booticon dtp-right booticon-right"></a></th>\n                                    </tr>\n                                </table>\n                            </div>\n                            <div class="select-date">\n                                <table>\n                                    <tr class="header">\n                                        <th><a href="javascript:void(0);" class="booticon dtp-left booticon-left"></a></th>\n                                        <th colspan="5"><a href="javascript:void(0);"><div class="year"></div></a></th>\n                                        <th><a href="javascript:void(0);" class="booticon dtp-right booticon-right"></a></th>\n                                    </tr>\n                                    <tr>\n                                        <th>日</th>\n                                        <th>一</th>\n                                        <th>二</th>\n                                        <th>三</th>\n                                        <th>四</th>\n                                        <th>五</th>\n                                        <th>六</th>\n                                    </tr>\n                                </table>\n                            </div>\n                        </div>\n                    ')
                };
            }
        };
    })();
    var skin = table.skin();

    //优先添加在head，其次是body
    $(document).find('head,body').first().append(skin);

    return 0;
})(window.$, window, document);

